#pragma once
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <string>
#include "Windows/SharedMemory.hpp"
#include <memory>
#include "SharedData.hpp"
#include <iostream>
#include "Windows/Dialog.hpp"
#include "Defines.hpp"
#include "Windows/ProcessReadWriteLock.hpp"

class Startup
{
private:
    CppWinApi::Windows::SharedMemory<APP_SHARED_MEMORY_UUID, SharedData> &mSharedMemory;
    std::string mUUID;

public:
    Startup() : mSharedMemory(CppWinApi::Windows::SharedMemory<APP_SHARED_MEMORY_UUID, SharedData>::GetInstance())
    {
        // 创建随机数生成器
        boost::uuids::random_generator generator;
        // 生成一个随机 UUID
        boost::uuids::uuid uuid = generator();
        mUUID = boost::uuids::to_string(uuid);
    }

    void Run(int workProcessId)
    {
        // 设置工作进程 id
        mSharedMemory.Action([](SharedData *data, int processId)
                             { data->WorkProcessId = processId; }, workProcessId);

        // 启动守护进程
        auto pi = CppWinApi::Windows::WinProcess::ForkBackgroundProcess(
            std::string("launch-daemon-process") + " " + mUUID);

        // 指数退避等待策略：1000ms, 2000ms, 4000ms
        for (int wait = 1000, count = 0; count <= 2; wait *= 2, ++count)
        {
            // 等待进程启动
            if (CppWinApi::Windows::WinProcess::WaitProcessExit(pi.GetProcessId(), wait) == WAIT_ABANDONED)
            {
                CppWinApi::Windows::Dialog::Show("start daemon-process failed.");
                return;
            }

            // 设置工作进程 id
            auto daemonProcessIsRunning = mSharedMemory.Action([](SharedData *data)
                                                               { return data->DaemonProcessIsRunning; });

            // 检查守护进程是否已正常运行
            if (daemonProcessIsRunning)
            {
                return;
            }
        }

        // 三次尝试后仍未成功
        CppWinApi::Windows::Dialog::Show("start daemon-process timeout.");
    }
};